﻿Imports Microsoft.VisualStudio.TestTools.UnitTesting

Imports ContactManager



'''<summary>
'''This is a test class for ContactServiceImplTest and is intended
'''to contain all ContactServiceImplTest Unit Tests
'''</summary>
<TestClass()> _
Public Class ContactServiceImplTest


    Private testContextInstance As TestContext
    Private conn_string As String = "provider=Microsoft.ACE.OLEDB.12.0;data source = ../../../../ContactManager/ContactManager/bin/Debug/contacts.accdb"
    Private testUtils As New UnitTestUtils(conn_string)
    Private contactService As ContactServiceImpl = New ContactServiceImpl(conn_string)


    '''<summary>
    '''Gets or sets the test context which provides
    '''information about and functionality for the current test run.
    '''</summary>
    Public Property TestContext() As TestContext
        Get
            Return testContextInstance
        End Get
        Set(value As TestContext)
            testContextInstance = Value
        End Set
    End Property

#Region "Additional test attributes"
    '
    'You can use the following additional attributes as you write your tests:
    '
    'Use ClassInitialize to run code before running the first test in the class
    '<ClassInitialize()>  _
    'Public Shared Sub MyClassInitialize(ByVal testContext As TestContext)
    'End Sub
    '
    'Use ClassCleanup to run code after all tests in a class have run
    '<ClassCleanup()>  _
    'Public Shared Sub MyClassCleanup()
    'End Sub
    '
    'Use TestInitialize to run code before running each test
    '<TestInitialize()>  _
    'Public Sub MyTestInitialize()
    'End Sub
    '
    'Use TestCleanup to run code after each test has run
    '<TestCleanup()>  _
    'Public Sub MyTestCleanup()
    'End Sub
    '
#End Region

    <TestMethod()> _
    Public Sub testAddContact()

        ' temp hack: both testUtils and contactService have to share same connection in order to allow them to see updates immediatly
        testUtils = New UnitTestUtils(contactService.getConn)

        Dim contact As Contact = DomainStubFactory.getContactStub()
        Assert.IsTrue(contact.id = -1)
        Assert.IsTrue(contact.emailList(0).id = -1)
        Assert.IsTrue(contact.phoneList(0).id = -1)
        Assert.IsTrue(contact.addressList(0).id = -1)

        Dim preContactCount As Long = testUtils.getRowCountFor(Tables.contacts)
        Dim preAddressCount As Long = testUtils.getRowCountFor(Tables.address)
        Dim prePhoneCount As Long = testUtils.getRowCountFor(Tables.phone)
        Dim preEmailCount As Long = testUtils.getRowCountFor(Tables.email)

        Assert.IsTrue(contactService.saveContact(contact))

        Dim postContactCount As Long = testUtils.getRowCountFor(Tables.contacts)
        Dim postAddressCount As Long = testUtils.getRowCountFor(Tables.address)
        Dim postPhoneCount As Long = testUtils.getRowCountFor(Tables.phone)
        Dim postEmailCount As Long = testUtils.getRowCountFor(Tables.email)

        Assert.AreEqual(1 + preContactCount, postContactCount)
        Assert.AreEqual(preEmailCount + contact.emailList.Count, postEmailCount)
        Assert.AreEqual(preAddressCount + contact.addressList.Count, postAddressCount)
        Assert.AreEqual(prePhoneCount + contact.phoneList.Count, postPhoneCount)

        Assert.IsTrue(contact.id > 0)
        Assert.IsTrue(contact.emailList(0).id > 0)
        Assert.IsTrue(contact.phoneList(0).id > 0)
        Assert.IsTrue(contact.addressList(0).id > 0)


    End Sub

    <TestMethod()> _
    Public Sub testGetContactById()

        ' Verify contact attributes
        Dim expectedContact = DomainStubFactory.getContactStub
        ' Not a good practice to have dependency on other test methods but done here due to lack of setup script
        contactService.saveContact(expectedContact)

        Dim actualContact As Contact = contactService.getContactById(expectedContact.id)

        Assert.IsNotNull(actualContact)
        Assert.AreEqual(expectedContact.id, actualContact.id)
        Assert.AreEqual(expectedContact.firstName, actualContact.firstName)
        Assert.AreEqual(expectedContact.lastName, actualContact.lastName)
        Assert.AreEqual(expectedContact.title, actualContact.title)
        Assert.AreEqual(expectedContact.displayName, actualContact.displayName)
        Assert.AreEqual(expectedContact.company, actualContact.company)

        ' Verify phone numbers
        Assert.IsNotNull(actualContact.phoneList)
        Assert.AreEqual(expectedContact.phoneList.Count, actualContact.phoneList.Count)
        Dim expectedPhone = expectedContact.phoneList(0)
        Dim actualPhone = actualContact.phoneList(0)
        Assert.IsNotNull(actualPhone)
        Assert.AreEqual(expectedPhone.id, actualPhone.id)
        Assert.AreEqual(expectedPhone.areaCode, actualPhone.areaCode)
        Assert.AreEqual(expectedPhone.prefix, actualPhone.prefix)
        Assert.AreEqual(expectedPhone.lineNumber, actualPhone.lineNumber)
        Assert.AreEqual(expectedPhone.ext, actualPhone.ext)
        Assert.AreEqual(expectedPhone.type, actualPhone.type)

        ' Verify emails
        Assert.IsNotNull(actualContact.emailList)
        Assert.AreEqual(expectedContact.emailList.Count, actualContact.emailList.Count)
        Dim expectedEmail = expectedContact.emailList(0)
        Dim actualEmail = actualContact.emailList(0)
        Assert.IsNotNull(actualEmail)
        Assert.AreEqual(expectedEmail.id, actualEmail.id)
        Assert.AreEqual(expectedEmail.address, actualEmail.address)
        Assert.AreEqual(expectedEmail.displayName, actualEmail.displayName)

        ' verify address
        Assert.IsNotNull(actualContact.addressList)
        Assert.AreEqual(expectedContact.addressList.Count, actualContact.addressList.Count)
        Dim expectedAddress = expectedContact.addressList(0)
        Dim actualAddress = actualContact.addressList(0)
        Assert.IsNotNull(actualAddress)
        Assert.AreEqual(expectedAddress.id, actualAddress.id)
        Assert.AreEqual(expectedAddress.street1, actualAddress.street1)
        Assert.AreEqual(expectedAddress.street2, actualAddress.street2)
        Assert.AreEqual(expectedAddress.city, actualAddress.city)
        Assert.AreEqual(expectedAddress.state, actualAddress.state)
        Assert.AreEqual(expectedAddress.zip, actualAddress.zip)


    End Sub


    <TestMethod()> _
    Public Sub testGetContactByIdForNotFound()

        Dim actualContact As Contact = contactService.getContactById(-100)
        Assert.IsNull(actualContact)
        
    End Sub


    <TestMethod()> _
    Public Sub testDeleteContact()

        Dim contactToBeDeleted As Contact = DomainStubFactory.getContactStub()
        contactService.saveContact(contactToBeDeleted)
        contactToBeDeleted = contactService.getContactById(contactToBeDeleted.id)
        Assert.IsNotNull(contactToBeDeleted)
        contactService.deleteContact(contactToBeDeleted.id)
        contactToBeDeleted = contactService.getContactById(contactToBeDeleted.id)
        Assert.IsNull(contactToBeDeleted)


    End Sub

    '''<summary>
    '''A test for updateContact
    '''</summary>
    <TestMethod()> _
    Public Sub testUpdateContact()

        Dim expectedContact = DomainStubFactory.getContactStub
        ' Not a good practice to have dependency on other test methods but done here due to lack of setup script
        contactService.saveContact(expectedContact)

        ' Update contact header info
        expectedContact = contactService.getContactById(expectedContact.id)
        expectedContact.firstName = StrReverse(expectedContact.firstName)
        expectedContact.lastName = StrReverse(expectedContact.lastName)
        expectedContact.displayName = StrReverse(expectedContact.displayName)
        expectedContact.title = StrReverse(expectedContact.title)
        expectedContact.company = StrReverse(expectedContact.company)

        ' Update phone info
        Dim expectedPhone = expectedContact.phoneList(0)
        expectedPhone.lineNumber = StrReverse(expectedPhone.lineNumber)
        expectedPhone.areaCode = StrReverse(expectedPhone.areaCode)
        expectedPhone.prefix = StrReverse(expectedPhone.prefix)
        expectedPhone.ext = StrReverse(expectedPhone.ext)

        ' Delete a phoneNumber
        expectedContact.phoneList.RemoveAt(1)

        ' Add new phone
        Dim newPhone = New PhoneNumber(888, 999, 1234, "HM")
        expectedContact.phoneList.Add(newPhone)


        ' Update address info
        Dim expectedAddress = expectedContact.addressList(0)
        expectedAddress.street1 = StrReverse(expectedAddress.street1)
        expectedAddress.street2 = StrReverse(expectedAddress.street2)
        expectedAddress.city = StrReverse(expectedAddress.city)
        expectedAddress.state = StrReverse(expectedAddress.state)
        expectedAddress.zip = StrReverse(expectedAddress.zip)

        ' Delete an address
        expectedContact.addressList.RemoveAt(1)

        ' Add new address
        Dim newAddress = New Address("111 Daisy Ln", "Humble", "CA", "98998")
        expectedContact.addressList.Add(newAddress)

        ' Update email info
        Dim expectedEmail = expectedContact.emailList(0)
        expectedEmail.address = StrReverse(expectedEmail.address)
        expectedEmail.displayName = StrReverse(expectedEmail.displayName)

        ' Delete an email
        expectedContact.emailList.RemoveAt(1)

        ' Add new address
        Dim newEmail = New Email("jbloch@example.com", "JB")
        expectedContact.emailList.Add(newEmail)


        contactService.saveContact(expectedContact)

        ' Verify contact header
        Dim actualContact As Contact = contactService.getContactById(expectedContact.id)
        Assert.AreEqual(expectedContact.firstName, actualContact.firstName)
        Assert.AreEqual(expectedContact.lastName, actualContact.lastName)
        Assert.AreEqual(expectedContact.title, actualContact.title)
        Assert.AreEqual(expectedContact.displayName, actualContact.displayName)
        Assert.AreEqual(expectedContact.company, actualContact.company)

        ' Verify phone count (added one, deleted one)
        Assert.AreEqual(expectedContact.phoneList.Count, actualContact.phoneList.Count)

        ' Verify updated phone info
        Dim actualPhone = actualContact.phoneList(0)
        Assert.AreEqual(expectedPhone.areaCode, actualPhone.areaCode)
        Assert.AreEqual(expectedPhone.prefix, actualPhone.prefix)
        Assert.AreEqual(expectedPhone.lineNumber, actualPhone.lineNumber)
        Assert.AreEqual(expectedPhone.ext, actualPhone.ext)

        ' Verify newly added Phone
        actualPhone = actualContact.phoneList(1)
        Assert.AreEqual(newPhone.areaCode, actualPhone.areaCode)
        Assert.AreEqual(newPhone.prefix, actualPhone.prefix)
        Assert.AreEqual(newPhone.lineNumber, actualPhone.lineNumber)
        Assert.AreEqual(newPhone.ext, actualPhone.ext)

        ' Verify address count (added one, deleted one)
        Assert.AreEqual(expectedContact.addressList.Count, actualContact.addressList.Count)

        ' Verify updated address info
        Dim actualAddress = actualContact.addressList(0)
        Assert.AreEqual(expectedAddress.street1, actualAddress.street1)
        Assert.AreEqual(expectedAddress.street2, actualAddress.street2)
        Assert.AreEqual(expectedAddress.city, actualAddress.city)
        Assert.AreEqual(expectedAddress.state, actualAddress.state)
        Assert.AreEqual(expectedAddress.zip, actualAddress.zip)

        ' Verify newly added address
        actualAddress = actualContact.addressList(1)
        Assert.AreEqual(newAddress.street1, actualAddress.street1)
        Assert.AreEqual(newAddress.street2, actualAddress.street2)
        Assert.AreEqual(newAddress.city, actualAddress.city)
        Assert.AreEqual(newAddress.state, actualAddress.state)
        Assert.AreEqual(newAddress.zip, actualAddress.zip)

        ' Verify address count (added one, deleted one)
        Assert.AreEqual(expectedContact.emailList.Count, actualContact.emailList.Count)

        ' Verify updated email
        Dim actualEmail = actualContact.emailList(0)
        Assert.AreEqual(expectedEmail.address, actualEmail.address)
        Assert.AreEqual(expectedEmail.displayName, actualEmail.displayName)

        ' Verify newly added email
        actualEmail = actualContact.emailList(1)
        Assert.AreEqual(newEmail.address, actualEmail.address)
        Assert.AreEqual(newEmail.displayName, actualEmail.displayName)

    End Sub

    '''<summary>
    '''A test for updateContact
    '''</summary>
    <TestMethod()> _
    Public Sub testUpdateContactWithNoEntities()

        Dim expectedContact = DomainStubFactory.getContactStub
        ' Not a good practice to have dependency on other test methods but done here due to lack of setup script
        contactService.saveContact(expectedContact)

        
        ' Clear All phones
        expectedContact.phoneList.Clear()
        ' Clear All Address
        expectedContact.addressList.Clear()
        ' Clear All Emails
        expectedContact.emailList.Clear()

        ' This should not blow up
        contactService.saveContact(expectedContact)

        Dim actualContact As Contact = contactService.getContactById(expectedContact.id)
        
        ' Verify phone count (should be zero)
        Assert.AreEqual(expectedContact.phoneList.Count, actualContact.phoneList.Count)
        ' Verify address count (should be zero)
        Assert.AreEqual(expectedContact.addressList.Count, actualContact.addressList.Count)
        ' Verify email count (should be zero)
        Assert.AreEqual(expectedContact.emailList.Count, actualContact.emailList.Count)

    End Sub

    <TestMethod()> _
    Public Sub testGetPhoneTypes()

        Dim phoneTypes As List(Of EntityType) = contactService.getPhoneTypes()
        Assert.IsNotNull(phoneTypes)
        Assert.IsTrue(phoneTypes.Count > 0)

    End Sub

    <TestMethod()> _
    Public Sub testGetAddressTypes()

        Dim addressTypes As List(Of EntityType) = contactService.getAddressTypes()
        Assert.IsNotNull(addressTypes)
        Assert.IsTrue(addressTypes.Count > 0)

    End Sub


End Class
